package com.zhang.goods.service.impl;

import cn.dev33.satoken.stp.StpUtil;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhang.goods.entity.Attrgroup;
import com.zhang.goods.entity.Attribute;

import com.zhang.brand.entity.Brand;
import com.zhang.brand.service.IBrandService;
import com.zhang.common.model.SkuEsModel;
import com.zhang.common.dto.SkuSearchDto;
import com.zhang.common.exception.myexception.ProductUpException;
import com.zhang.common.util.result.R;
import com.zhang.common.util.result.RUtils;
import com.zhang.common.util.time.TimeUtils;

import com.zhang.goods.entity.Category;
import com.zhang.goods.service.ICategoryService;
import com.zhang.goods.entity.*;
import com.zhang.goods.service.*;
import com.zhang.goods.dto.*;
import com.zhang.goods.vo.AttrValueWithSkuIdVo;
import com.zhang.goods.vo.ConfirmOrderSkuVo;
import com.zhang.goods.vo.SkuItemVo;
import com.zhang.goods.vo.SkuInfoVo;
import com.zhang.search.service.IProductElasticSearchService;
import com.zhang.warehouse.service.IWareSkuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class GoodsServiceImpl implements IGoodsService {
    @Autowired
    private ISpuInfoService spuInfoService;
    @Autowired
    private IProductAttrValueService productAttrValueService;
    @Autowired
    private ISkuInfoService skuInfoService;
    @Autowired
    private ISkuSaleAttrValueService skuSaleAttrValueService;
    @Autowired
    private ISpuImgService spuImgService;
    @Autowired
    private ISpuDescImgService spuDescImgService;
    @Autowired
    private ISkuImagsService skuImagsService;
    @Autowired
    private ICategoryService categoryService;
    @Autowired
    private IBrandService brandService;
    @Autowired
    private IAttributeService attributeService;
    @Autowired
    private IWareSkuService wareSkuService;
    @Autowired
    private IProductElasticSearchService IProductElasticSearchService;
    @Autowired
    private IAttrgroupService groupService;

    @Override
    @Transactional
    public R goodsSave(GoodsSaveDto goodsSaveDto) {
        SpuInfo spuInfo = new SpuInfo();
        SpuInfoDto spuInfoDto = goodsSaveDto.getSpuInfoDto();
        List<AttrGroupList> groupList = goodsSaveDto.getAttrGroupList();
        /*第一步：保存spu信息*/
        if (spuInfoDto != null) {
            spuInfo.setBusinessId(StpUtil.getLoginIdAsLong());
            spuInfo.setSpuName(spuInfoDto.getSpuName());
            spuInfo.setSpuDescription(spuInfoDto.getSpuDescription());
            /*先不发布*/
            spuInfo.setState(1);
            spuInfo.setBrandId(spuInfoDto.getBrandId());
            spuInfo.setWeight(spuInfoDto.getWeight());
            spuInfo.setCategoryId(spuInfoDto.getCategoryId());
            spuInfo.setCreateTime(TimeUtils.getLocalDateStr());
            spuInfoService.save(spuInfo);
        }

        /*保存介绍大图*/
        for (Long img : spuInfoDto.getIntroduceImage()) {
            SpuDescImg spuDescImg = new SpuDescImg();
            spuDescImg.setImgId(img);
            spuDescImg.setSpuId(spuInfo.getId());
            spuDescImgService.save(spuDescImg);
        }

        /*保存spu的图集*/
        for (Long atlas : spuInfoDto.getAtlas()) {
            SpuImg spuImg = new SpuImg();
            spuImg.setImgId(atlas);
            spuImg.setSpuId(spuInfo.getId());
            spuImgService.save(spuImg);
        }

        /*spu默认图片*/
        Long spuDefaultImage = spuInfoDto.getSpuDefaultImage();
        log.info("查看上传的图片是否是空的"+spuDefaultImage);
        if (spuDefaultImage != null) {
            SpuImg spuImg = new SpuImg();
            spuImg.setImgId(spuDefaultImage);
            spuImg.setSpuId(spuInfo.getId());
            spuImg.setIsDefault(0);//默认
            UpdateWrapper<SpuImg> wrapper = new UpdateWrapper<>();
            wrapper.eq("img_id", spuDefaultImage).eq("spu_id", spuInfo.getId());
            spuImgService.saveOrUpdate(spuImg, wrapper);//如果存在则更新
        } else {
            /*如果为空则查询出一个为默认*/
            QueryWrapper<SpuImg> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("spu_id", spuInfo.getId());
            SpuImg one = spuImgService.getOne(queryWrapper, false);/*查询出多个时不抛出异常*/
            if (one!=null){
                one.setIsDefault(0);
                spuImgService.updateById(one);
            }
        }

        /*第二步：保存属性分组的值（规格参数的值）
         * 2.1遍历*/
        if (groupList != null && groupList.size() > 0) {
            ArrayList<ProductAttrValue> productAttrValues = new ArrayList<>();
            log.info("这里是分组属性集合{}" , JSON.toJSONString(groupList));
            groupList.stream().forEach(item -> {
                if (item.getAttrList() != null && item.getAttrList().size() > 0) {
                    System.out.println("这里是属性" + JSON.toJSONString(item.getAttrList()));
                    item.getAttrList().stream().forEach(attrItem -> {
                        log.info("这里是属性值{}" ,JSON.toJSONString(attrItem.getAttrValues()));
                        if (attrItem.getAttrValues() != null || attrItem.getAttrValues().size() > 0) {
                            attrItem.getAttrValues().stream().forEach(attrValueItem -> {
                                ProductAttrValue productAttrValue = new ProductAttrValue();
                                productAttrValue.setAttrName(attrItem.getAttrName());//属性名称
                                productAttrValue.setAttrId(attrItem.getId());//attrId
                                productAttrValue.setAttrValue(attrValueItem);//属性值
                                productAttrValue.setQuickShow(attrItem.getQuickShow());//是否快速显示
                                productAttrValue.setSpuId(spuInfo.getId());//spu的id
                                productAttrValue.setAttrSort(0);
                                productAttrValues.add(productAttrValue);
                            });
                        }
                    });
                }
            });
            productAttrValueService.saveBatch(productAttrValues);
        }
        /*第三步：
        3.1保存sku(单品)信息
        3.2保存销售属性值（sku的属性值）信息
         * */
        if (goodsSaveDto.getSkuInfoDto() != null && goodsSaveDto.getSkuInfoDto().size() > 0) {
            for (SkuInfoDto skuInfoDto : goodsSaveDto.getSkuInfoDto()) {
//           3.1保存sku(单品)信息
                SkuInfo skuInfo = new SkuInfo();
                BeanUtils.copyProperties(skuInfoDto, skuInfo);
                skuInfo.setBrandId(spuInfoDto.getBrandId());
                skuInfo.setCategoryId(spuInfoDto.getCategoryId());
                skuInfo.setSpuId(spuInfo.getId());
                skuInfo.setSkuDefaultImg(skuInfoDto.getSkuDefaultImg());
                skuInfoService.save(skuInfo);
                Long skuInfoId = skuInfo.getId();
//                3.1.1保存sku图片信息
                if (skuInfoDto.getSkuImgs().size() > 0) {
                    for (Long skuImg : skuInfoDto.getSkuImgs()) {
                        SkuImags skuImag = new SkuImags();
                        skuImag.setSkuId(skuInfoId);
                        skuImag.setImgId(skuImg);
                        if (skuImg.equals(skuInfoDto.getSkuDefaultImg())) {
                            skuImag.setIsDefault(0);
                        }
                        skuImagsService.save(skuImag);
                    }
                }
//           3.2保存销售属性值（sku的属性值）信息
                for (Attr attr : skuInfoDto.getAttr()) {
                    SkuSaleAttrValue skuSaleAttrValue = new SkuSaleAttrValue();
                    BeanUtils.copyProperties(attr, skuSaleAttrValue);
                    skuSaleAttrValue.setSkuId(skuInfoId);
                    skuSaleAttrValueService.save(skuSaleAttrValue);
                }
            }
        }
        log.info("商品保存成功");
        return RUtils.successMsg("保存成功");
    }

    @Override
    public Page getMySpuList(Integer pageNum, Integer pageSize, SpuSearchDto spuSearchDto) {
        return spuInfoService.getMySpuListPage(pageNum, pageSize, spuSearchDto);
    }

    List getSpuListVo(List<SpuInfo> spuInfoList) {
        /*处理图片路径*/
        List<SkuInfoVo> collect = spuInfoList.stream().map(item -> {
            SkuInfoVo vo = new SkuInfoVo();
            BeanUtils.copyProperties(item, vo);
            Long imgIdBySpuId = spuImgService.getImgIdBySpuId(item.getId());
            return vo;
        }).collect(Collectors.toList());
        return collect;
    }

    List<SkuInfoVo> getSkuListVo(List<SkuInfo> skuInfoList) {
        /*处理图片路径*/
        List<SkuInfoVo> collect = skuInfoList.stream().map(item -> {
            SkuInfoVo vo = new SkuInfoVo();
            BeanUtils.copyProperties(item, vo);
            Long imgIdBySkuId = skuImagsService.getDefalutImgIdBySkuId(item.getId());
            return vo;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public IPage getSkuList(SkuSearchDto skuSearchDto) {
        return skuInfoService.getSkuListPage(skuSearchDto);
    }

    @Override
    public void modifySku(SkuInfoDto skuInfoDto) {
        skuInfoService.modifySku(skuInfoDto);
    }

    @Override
    public List getSpuAtlasInfo(Long spuId) {
        List<SpuImg> spuImgs = spuImgService.list(new QueryWrapper<SpuImg>().eq("spu_id", spuId));
        List<Long> collect = spuImgs.stream().map(SpuImg::getImgId).collect(Collectors.toList());
        return collect;
    }

    @Override
    @Transactional
    public R goodsUp(Long spuId) {
        System.out.println("上架");
        LocalDateTime now = LocalDateTime.now();
        List<SkuEsModel> skuEsModels = null;
        /*查询当前sku的所有可以被检索的规格属性*/
        List<ProductAttrValue> attrList = productAttrValueService.listBySpuId(spuId);
        List<Long> attrIds = attrList.stream().map(attr -> attr.getAttrId()).collect(Collectors.toList());
        /*筛选出可以被检索的属性attr*/
        List<Long> searchAttrIds = attributeService.selectSearchAttrIds(attrIds);
        HashSet<Long> searchAttrIdsSet = new HashSet<>(searchAttrIds);//去掉重复的
//        获取SkuEsModel的attrs的值---》Attr
        List<SkuEsModel.Attrs> attrsList = attrList.stream().filter(item -> {
            return searchAttrIdsSet.contains(item.getAttrId());//判断attr是否在这个集合里面，不是就过滤掉
        }).map(item -> {
            SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
            BeanUtils.copyProperties(item, attrs);
            return attrs;
        }).collect(Collectors.toList());

        /*向ElasticSearch保存数据
         *   1.查询sku信息*/
        List<SkuInfo> skuInfoList = skuInfoService.listBySpuId(spuId);
        SpuInfo byId = spuInfoService.getById(spuId);
        skuEsModels = skuInfoList.stream().map(sku -> {
            SkuEsModel skuEsModel = new SkuEsModel();
            /*封装*/
            BeanUtils.copyProperties(sku, skuEsModel);
            skuEsModel.setSkuId(sku.getId());
            Category category = categoryService.getById(sku.getCategoryId());
            skuEsModel.setCategoryName(category.getName());
            Brand brand = brandService.getById(sku.getBrandId());
            skuEsModel.setBrandName(brand.getName());
            skuEsModel.setSkuPrice(sku.getPrice());
            skuEsModel.setBrandImg(brand.getLogo());
            skuEsModel.setAttrs(attrsList);
            skuEsModel.setHotScore(0L);
            skuEsModel.setBusinessId(byId.getBusinessId());
            skuEsModel.setUpTime(now);
            Integer stock = wareSkuService.getStockBySkuId(sku.getId());
            if (stock == 0) {
                skuEsModel.setHasStock(false);
            } else {
                skuEsModel.setHasStock(true);
            }
            return skuEsModel;
        }).collect(Collectors.toList());
// 向ES中保存商品数据
        try {
            IProductElasticSearchService.productUp(skuEsModels);
        } catch (Exception e) {
            throw new ProductUpException(spuId.toString());
        }
        /*更改mysql内spu的状态为上架*/
        SpuInfo spuInfo = new SpuInfo();
        spuInfo.setId(spuId);
        spuInfo.setState(0);
        spuInfo.setUpTime(now);
        spuInfoService.updateById(spuInfo);
        return RUtils.successMsg("上架成功");
    }


    @Override
    public SkuItemVo getSkuItem(Long skuId) {
        SkuItemVo vo = new SkuItemVo();
        /*1 获取基本信息：标题，价格等信息*/
        SkuInfo skuInfo = skuInfoService.getById(skuId);
        vo.setSkuInfo(skuInfo);
        /*1.2   获取图片信息*/
        List<SkuImags> skuImags = skuImagsService.getBySkuId(skuId);
        vo.setSkuImags(skuImags);
        SpuInfo spuInfo = spuInfoService.getById(skuInfo.getSpuId());
        /* 2    获取spu销售属性组合信息*/
        /* 2.1查询当前所属分类有哪些销售属性*/
        List<Attribute> list = attributeService.listSaleAttrByCategoryId(spuInfo.getCategoryId());
        log.info("销售属性有哪些？{}", list.toString());
        /* 2.2查询当前spu有哪些sku，在后面查询销售属性值的时候需要用到*/
        List<SkuInfo> skuInfoList = skuInfoService.listBySpuId(spuInfo.getId());
        List<Long> skuIds = skuInfoList.stream().map(SkuInfo::getId).collect(Collectors.toList());
        List<SkuItemVo.SkuItemSaleAttrVo> voList = list.stream().map(item -> {
            SkuItemVo.SkuItemSaleAttrVo itemSaleAttrVo = new SkuItemVo.SkuItemSaleAttrVo();
            itemSaleAttrVo.setAttrId(item.getId());
            itemSaleAttrVo.setAttrName(item.getAttrName());
            List<SkuSaleAttrValue> skuSaleAttrValueList = skuSaleAttrValueService.listByAttrIdAndSkuIds(item.getId(), skuIds);
            Set<String> set = skuSaleAttrValueList.stream().map(SkuSaleAttrValue::getAttrValue).collect(Collectors.toSet());//去重
            /*查询出这些value值对应的有哪些skuid具有这个value值*/
            List<AttrValueWithSkuIdVo> attrValueWithSkuIdVos = new ArrayList<>();
            /*生成AttrValueWithSkuIdVo*/
            for (String value : set) {
                List<Long> skuIdsByValues = skuSaleAttrValueService.SkuIdListBySkuIdsAndValue(skuIds, value);
                AttrValueWithSkuIdVo attrValueWithSkuIdVo = new AttrValueWithSkuIdVo();
                attrValueWithSkuIdVo.setSkuIds(skuIdsByValues);
                attrValueWithSkuIdVo.setAttrValue(value);
                attrValueWithSkuIdVos.add(attrValueWithSkuIdVo);
            }
            itemSaleAttrVo.setAttValues(attrValueWithSkuIdVos);
            return itemSaleAttrVo;
        }).collect(Collectors.toList());
        vo.setSkuItemSaleAttrVos(voList);
        /* 3    获取spu介绍*/
        SpuDescImg spuDescImg = spuDescImgService.getBySpuId(skuInfo.getSpuId());
        vo.setSpuDescImg(spuDescImg);
        /* 4    获取spu的规格参数信息*/
        /* 4.1  查出分组名，查出规格参数信息*/
        /* 4.1,1    查询表asso_attr_attrgroup，以及表my_attrgroup*/
        List<Attrgroup> groups = groupService.listByCategoryId(spuInfo.getCategoryId());
        /* 4.2  遍历分组，查出这个分组下的所有规格参数（attr数据*/
        List<SkuItemVo.SpuItemAttrGroupVo> collect = groups.stream().map(item -> {
            SkuItemVo.SpuItemAttrGroupVo groupVo = new SkuItemVo.SpuItemAttrGroupVo();
            groupVo.setGroupName(item.getGroupName());
            ArrayList<SkuItemVo.SpuBaseAttrVo> spuBaseAttrVos = new ArrayList<>();
            /* 4.2.1    查询表my_attribute*/
            List<Attribute> attrByAttrgroupId = attributeService.getAttrByAttrgroupId(item.getId());
            /*拿到所有的规格参数（attr）数据，查询这些规格参数的值（value）*/
            if (attrByAttrgroupId != null && attrByAttrgroupId.size() > 0) {
                for (Attribute attribute : attrByAttrgroupId) {
                    /*查询my_product_attr_value表，获取规格参数的值*/
                    SkuItemVo.SpuBaseAttrVo spuBaseAttrVo = new SkuItemVo.SpuBaseAttrVo();
                    spuBaseAttrVo.setAttrName(attribute.getAttrName());
                    ProductAttrValue attrValue = productAttrValueService.getByAttrIdAndSpuId(attribute.getId(), spuInfo.getId());
                    if (attrValue != null) {
                        spuBaseAttrVo.setAttrValue(attrValue.getAttrValue());
                    } else {
                        log.error("这个id为{}的规格参数，当前的spu没有对应的规格参数值", attribute.getId().toString());
                    }
                    spuBaseAttrVos.add(spuBaseAttrVo);
                }
            }
            groupVo.setAttrValues(spuBaseAttrVos);
            return groupVo;
        }).collect(Collectors.toList());
        vo.setGroupAttrs(collect);
//        获取库存
        Integer stockBySkuId = wareSkuService.getStockBySkuId(skuId);
        vo.setSkuStock(stockBySkuId);
        return vo;
    }

    @Override
    public List<ConfirmOrderSkuVo> getOrderConfirmSkuInfo(List<Long> skuIds) {
        return skuInfoService.getOrderConfirmSkuInfo(skuIds);
    }
}
